﻿using ImageK.Gui;
using ImageK.IO;
using ImageK.Macros;
using ImageK.Plugin.Frame;
using ImageK;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Intrinsics.X86;
using System.Text;
using System.Threading.Tasks;
using static System.Net.Mime.MediaTypeNames;
using System.Xml.Linq;

namespace ImageK.IO
{
    /** This class displays a dialog window from 
	which the user can save a file. */
    public class SaveDialog
    {

        private string dir;
        private string name;
        private string _title;
        private string ext;

        /** Displays a file save dialog with 'title' as the 
            title, 'defaultName' as the initial file name, and
            'extension' (e.g. ".tif") as the default extension.
        */
        public SaveDialog(string title, string defaultName, string extension)
        {
            this._title = title;
            ext = extension;
            if (isMacro())
                return;
            string defaultDir = OpenDialog.getDefaultDirectory();
            defaultName = setExtension(defaultName, extension);
            if (Prefs.useJFileChooser)
                jSave(title, defaultDir, defaultName);
            else
                save(title, defaultDir, defaultName);
            if (name!=null && dir!=null)
                OpenDialog.setDefaultDirectory(ref dir);
            IJ.ShowStatus(title+": "+dir+name);
        }

        /** Displays a file save dialog, using the specified 
            default directory and file name and extension. */
        public SaveDialog(string title, string defaultDir, string defaultName, string extension)
        {
            this._title = title;
            ext = extension;
            if (isMacro())
                return;
            defaultName = setExtension(defaultName, extension);
            if (Prefs.useJFileChooser)
                jSave(title, defaultDir, defaultName);
            else
                save(title, defaultDir, defaultName);
            IJ.ShowStatus(title+": "+dir+name);
        }

        bool isMacro()
        {
            // string macroOptions = Macro.getOptions();
            // if (macroOptions!=null)
            // {
            //     string path = Macro.getValue(macroOptions, title, null);
            //     if (path==null)
            //         path = Macro.getValue(macroOptions, "path", null);
            //     if (path!=null && path.indexOf(".")==-1 && !((new File(path)).exists()))
            //     {
            //         // Is 'path' a macro variable?
            //         if (path.startsWith("&")) path=path.substring(1);
            //         Interpreter interp = Interpreter.getInstance();
            //         string path2 = interp!=null ? interp.getStringVariable(path) : null;
            //         if (path2!=null) path = path2;
            //     }
            //     if (path!=null)
            //     {
            //         Opener o = new Opener();
            //         dir = o.getDir(path);
            //         name = o.getName(path);
            //         return true;
            //     }
            // }
            return false;
        }

        public static string setExtension(string name, string extension)
        {
            if (name==null || extension==null || extension.Length==0)
                return name;
            int dotIndex = name.LastIndexOf(".");
            if (dotIndex>=0 && (name.Length-dotIndex)<=5)
            {
                if (dotIndex+1<name.Length && Char.IsDigit(name[dotIndex+1]))
                    name += extension;
                else
                    name = name.Substring(0, dotIndex) + extension;
            }
            else if (!name.EndsWith(extension))
                name += extension;
            return name;
        }

        // Save using JFileChooser.
        void jSave(string title, string defaultDir, string defaultName)
        {
            // LookAndFeel saveLookAndFeel = Java2.getLookAndFeel();
            // Java2.setSystemLookAndFeel();
            // if (EventQueue.isDispatchThread())
            //     jSaveDispatchThread(title, defaultDir, defaultName);
            // else
            //     jSaveInvokeAndWait(title, defaultDir, defaultName);
            // Java2.setLookAndFeel(saveLookAndFeel);
        }

        // Save using JFileChooser.
        // assumes we are running on the event dispatch thread
        void jSaveDispatchThread(string title, string defaultDir, string defaultName)
        {
            // JFileChooser fc = new JFileChooser();
            // fc.setDialogTitle(title);
            // fc.setDragEnabled(true);
            // fc.setTransferHandler(new DragAndDropHandler(fc));
            // if (defaultDir!=null)
            // {
            //     File f = new File(defaultDir);
            //     if (f!=null)
            //         fc.setCurrentDirectory(f);
            // }
            // if (defaultName!=null)
            //     fc.setSelectedFile(new File(defaultName));
            // int returnVal = fc.showSaveDialog(IJ.getInstance());
            // if (returnVal!=JFileChooser.APPROVE_OPTION)
            // { Macro.abort(); return; }
            // File f = fc.getSelectedFile();
            // if (f.exists())
            // {
            //     int ret = JOptionPane.showConfirmDialog(fc,
            //         "The file "+ f.getName() + " already exists. \nWould you like to replace it?",
            //         "Replace?",
            //         JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
            //     if (ret!=JOptionPane.OK_OPTION) f = null;
            // }
            // if (f==null)
            //     Macro.abort();
            // else
            // {
            //     dir = fc.getCurrentDirectory().getPath()+File.separator;
            //     name = fc.getName(f);
            //     if (noExtension(name))
            //     {
            //         if (".raw".equals(ext))
            //             ext = null;
            //         name = setExtension(name, ext);
            //     }
            // }
        }

        // Save using JFileChooser. Runs on event
        // dispatch thread to avoid thread deadlocks.
        void jSaveInvokeAndWait(string title, string defaultDir, string defaultName)
        {
            // try
            // {
            //     EventQueue.invokeAndWait(new Runnable()
            //     {
            //
            //     public void run()
            //     {
            //         JFileChooser fc = new JFileChooser();
            //         fc.setDialogTitle(title);
            //         fc.setDragEnabled(true);
            //         fc.setTransferHandler(new DragAndDropHandler(fc));
            //         if (defaultDir!=null)
            //         {
            //             File f = new File(defaultDir);
            //             if (f!=null)
            //                 fc.setCurrentDirectory(f);
            //         }
            //         if (defaultName!=null)
            //             fc.setSelectedFile(new File(defaultName));
            //         int returnVal = fc.showSaveDialog(IJ.getInstance());
            //         if (returnVal!=JFileChooser.APPROVE_OPTION)
            //         { Macro.abort(); return; }
            //         File f = fc.getSelectedFile();
            //         if (f.exists())
            //         {
            //             int ret = JOptionPane.showConfirmDialog(fc,
            //                 "The file "+ f.getName() + " already exists. \nWould you like to replace it?",
            //                 "Replace?",
            //                 JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
            //             if (ret!=JOptionPane.OK_OPTION) f = null;
            //         }
            //         if (f==null)
            //             Macro.abort();
            //         else
            //         {
            //             dir = fc.getCurrentDirectory().getPath()+File.separator;
            //             name = fc.getName(f);
            //             if (noExtension(name))
            //             {
            //                 if (".raw".equals(ext))
            //                     ext = null;
            //                 name = setExtension(name, ext);
            //             }
            //         }
            //     }
            // });
            // } catch (Exception e) {}
        }

        // Save using FileDialog
        void save(string title, string defaultDir, string defaultName)
        {
            ImageK ij = IJ.GetInstance();
            Form parent = ij!=null ? ij : new Form();
            // FileDialog fd = new FileDialog(parent, title, FileDialog.SAVE);
            // if (defaultName!=null)
            //     fd.setFile(defaultName);
            // if (defaultDir!=null)
            // {
            //     if (IJ.isWindows() && defaultDir.contains("/"))
            //     {
            //         File f = new File(defaultDir);
            //         if (f.isDirectory())
            //             try
            //             {
            //                 defaultDir = f.getCanonicalPath();
            //             }
            //             catch (IOException e) { }
            //     }
            //     fd.setDirectory(defaultDir);
            // }
            // fd.show();
            SaveFileDialog fd = new SaveFileDialog();
            fd.Title = title;
            if(!string.IsNullOrEmpty(defaultName))
                fd.FileName = defaultName;
            if (!string.IsNullOrEmpty(defaultDir))
            {
                DirectoryInfo dirInfo = new DirectoryInfo(defaultDir);
                if (dirInfo.Exists)
                {
                    try
                    {
                        defaultDir = dirInfo.FullName;
                    }
                    catch (IOException e) { }
                }
                fd.InitialDirectory = defaultDir;
            }

            try
            {
                if (fd.ShowDialog() == DialogResult.OK)
                {
                    var fileName = fd.FileName;
                    name = Path.GetFileName(fileName);
                    string origName = name;
                    if (noExtension(name))
                    {
                        // if (".raw".Equals(ext))
                        //     ext = null;
                        // name = setExtension(name, ext);
                        // bool dialog = name != null && !name.Equals(origName) && IJ.isMacOSX() && !IJ.isMacro();
                        // if (dialog)
                        // {
                        //     File f = new File(fd.getDirectory() + getFileName());
                        //     if (!f.exists()) dialog = false;
                        // }
                        //
                        // if (dialog)
                        // {
                        //     Font font = new Font("SansSerif", Font.BOLD, 12);
                        //     GenericDialog gd = new GenericDialog("Replace File?");
                        //     gd.addMessage("\"" + name + "\" already exists.\nDo you want to replace it?", font);
                        //     gd.addMessage("To avoid this dialog, enable"
                        //                   + "\n\"Show all filename extensions\"\nin Finder Preferences.");
                        //     gd.setOKLabel("Replace");
                        //     gd.showDialog();
                        //     if (gd.wasCanceled())
                        //         name = null;
                        // }
                    }

                    if (IJ.debugMode) IJ.log(origName + "->" + name);
                    dir = Path.GetDirectoryName(fileName);
                    if (name == null)
                        Macro.abort();


                    if (ij == null)
                        parent.Dispose();
                }
            }
            catch (Exception ex)
            {

            }
        }

        private bool noExtension(string name)
        {
            if (name==null) return false;
            int dotIndex = name.IndexOf(".");
            return dotIndex==-1 || (name.Length-dotIndex)>5;
        }

        /** Returns the selected directory. */
        public string getDirectory()
        {
            OpenDialog.setLastDirectory(dir);
            return dir;
        }

        /** Returns the selected file name. */
        public string getFileName()
        {
            if (name!=null)
            {
                // if (Recorder.record && dir!=null)
                //     Recorder.recordPath(title, dir+name);
                OpenDialog.setLastName(name);
            }
            return name;
        }

        public static string getPath(ImagePlus imp, string extension)
        {
            string title = imp!=null ? imp.getTitle() : "Untitled";
            SaveDialog sd = new SaveDialog("Save As", title, extension);
            if (sd.getFileName()==null)
                return null;
            else
                return sd.getDirectory()+sd.getFileName();
        }
			        
    }
}
